package com.lonni.rpc.core.socket;

import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;

/**
 *
 * @author: Lonni
 * @date: 2024/7/9 0009 9:30
 */
public class SocketUtil implements Serializable {
    private final static Logger log = LoggerFactory.getLogger(SocketUtil.class);

    private final static String logBanner = "\n\n" + "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" + "*                                                                                   *\n" + "*                                                                                   *\n" + "*                   {}  started on  {}.                        *\n" + "*                                                                                   *\n" + "*                                                                                   *\n" + "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n";




    public static void bindAfterServer(ChannelFuture channelFuture, EventLoopGroup boosGroup, EventLoopGroup workGroup) {
        bindAfter("RpcNettyServer", channelFuture, boosGroup, workGroup);
    }

    public static void bindAfterClient(ChannelFuture channelFuture, EventLoopGroup workGroup) {
        bindAfter("RpcNettyClient", channelFuture, null, workGroup);
    }

    static void bindAfter(String serverName,
                          ChannelFuture channelFuture,
                          EventLoopGroup boosGroup,
                          EventLoopGroup workGroup

    ) {
        channelFuture.channel().newSucceededFuture().addListener(future -> {
            /**
             * 注册jvm钩子函数
             */
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
                @Override
                public void run() {
                    log.info("jvm钩子函数,优雅关闭netty...");
                    workGroup.shutdownGracefully();
                    if (boosGroup != null) {
                        boosGroup.shutdownGracefully();
                    }
                }
            }));
            log.info(logBanner, serverName, channelFuture.channel().localAddress().toString());
        });
        channelFuture.channel().closeFuture().addListener(future -> destroy(boosGroup, workGroup));

    }

    static void destroy(EventLoopGroup boosGroup, EventLoopGroup workGroup) {
        if (boosGroup != null && !boosGroup.isShuttingDown() && !boosGroup.isShutdown()) {
            try {
                boosGroup.shutdownGracefully();
            } catch (Exception ignore) {
                log.error("关闭boosGroup异常", ignore);
            }
        }

        if (workGroup != null && !workGroup.isShuttingDown() && !workGroup.isShutdown()) {
            try {
                workGroup.shutdownGracefully();
            } catch (Exception ignore) {
                log.error("关闭workGroup异常", ignore);
            }
        }
   }

}



